﻿using System.Collections.Generic;
using System.Web.UI;

namespace SBToolkit.Web
{
    /// <summary>
    /// Helper class for generic web <see cref="Control"/>s.
    /// </summary>
    public static class ControlHelper
    {
        /// <summary>
        /// Gets the parent control.
        /// </summary>
        /// <typeparam name="T">Type of control to find.</typeparam>
        /// <param name="control">The control.</param>
        /// <returns>Parent control.</returns>
        public static T GetParentControl<T>(this Control control) where T : Control
        {
            for (Control ctrl = control.Parent; ctrl != null; ctrl = ctrl.Parent)
            {
                if (ctrl is T)
                {
                    return (T)ctrl;
                }
            }

            return null;
        }

        /// <summary>
        /// Gets the child control.
        /// </summary>
        /// <typeparam name="T">Type of control to find.</typeparam>
        /// <param name="control">The control.</param>
        /// <returns>Child control.</returns>
        public static T GetChildControl<T>(this Control control) where T : Control
        {
            if (control is T)
            {
                return (T)control;
            }

            if (control.HasControls())
            {
                foreach (Control ctrl in control.Controls)
                {
                    T retCtrl;
                    if ((retCtrl = GetChildControl<T>(ctrl)) != null)
                    {
                        return retCtrl;
                    }
                }
            }

            return null;
        }

        /// <summary>
        /// Gets the child control.
        /// </summary>
        /// <typeparam name="T">Type of control to find.</typeparam>
        /// <param name="control">The control.</param>
        /// <param name="id">ID of control to find.</param>
        /// <returns>Child control</returns>
        public static T GetChildControl<T>(this Control control, string id) where T : Control
        {
            if (control is T && control.ID == id)
            {
                return (T)control;
            }

            if (control.HasControls())
            {
                foreach (Control ctrl in control.Controls)
                {
                    T retCtrl;
                    if ((retCtrl = GetChildControl<T>(ctrl, id)) != null)
                    {
                        return retCtrl;
                    }
                }
            }

            return null;
        }

        /// <summary>
        /// Gets child control collection.
        /// </summary>
        /// <typeparam name="T">Type of control to find.</typeparam>
        /// <param name="control">The control.</param>
        /// <returns>Child control collection.</returns>
        public static IEnumerable<T> GetChildControlCollection<T>(this Control control) where T : Control
        {
            return GetChildControlCollection(control.Controls, new List<T>());
        }

        /// <summary>
        /// Gets child control collection.
        /// </summary>
        /// <typeparam name="T">Type of control to find.</typeparam>
        /// <param name="collection">Collection to traverse.</param>
        /// <param name="controls">Child control collection.</param>
        /// <returns>Child control collection.</returns>
        private static IEnumerable<T> GetChildControlCollection<T>(ControlCollection collection, ICollection<T> controls) where T : Control
        {
            foreach (Control ctrl in collection)
            {
                if (ctrl is T)
                {
                    controls.Add(ctrl as T);
                }

                if (ctrl.HasControls())
                {
                    GetChildControlCollection(ctrl.Controls, controls);
                }
            }

            return controls;
        }
    }
}